home *** CD-ROM | disk | FTP | other *** search
/ Ham Radio 2000 #1 / Ham Radio 2000.iso / ham2000 / tcp_ip / wnos / wn941101 / dirutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-10  |  8.7 KB  |  414 lines

  1. /* dirutil.c - MS-DOS directory reading routines
  2.  *
  3.  * Bdale Garbee, N3EUA, Dave Trulli, NN2Z, and Phil Karn, KA9Q
  4.  * Directory sorting by Mike Chepponis, K3MC
  5.  * New version using regs.h by Russell Nelson.
  6.  * Rewritten for Turbo-C 2.0 routines by Phil Karn, KA9Q 25 March 89
  7.  *
  8.  * Changed commas to dots for European use :-) - DB3FL.910216
  9.  *
  10.  */
  11.  
  12. #include <stdio.h>
  13. #include <dir.h>
  14. #include <dos.h>
  15. #include <stdlib.h>
  16. #include <ctype.h>
  17. #include "global.h"
  18. #include "dirutil.h"
  19. #include "commands.h"
  20. #include "files.h"
  21.  
  22. #ifdef    XXX
  23. static int getdir_nosort __ARGS((char *path,int full,FILE *file));
  24. #endif
  25.  
  26. #define REGFILE    (FA_HIDDEN|FA_SYSTEM|FA_DIREC)
  27.  
  28. #define    insert_ptr(list,new)    (new->next = list,list = new)
  29.  
  30. struct dirsort {
  31.     struct dirsort *next;
  32.     struct ffblk de;
  33. };
  34. #define    NULLSORT (struct dirsort *)0
  35.  
  36. /*
  37.  * Return a string with commas every 3 positions.
  38.  * the original string is replace with the string with commas.
  39.  * The caller must be sure that there is enough room for the resultant
  40.  * string.
  41.  *
  42.  * k3mc 4 Dec 87
  43.  *
  44.  * Changed to dots instead of commas for european use - DB3FL.910216
  45.  *
  46.  */
  47. static void near
  48. commas(dest)
  49. char *dest;
  50. {
  51.     char *src, *core;    /* Place holder for malloc */
  52.     unsigned cc;        /* The comma counter */
  53.  
  54.     unsigned len = strlen(dest);
  55.     /* Make a copy, so we can muck around */
  56.     core = src = strxdup(dest);
  57.  
  58.     cc = (len-1) % 3 + 1;    /* Tells us when to insert a comma */
  59.  
  60.     while(*src != '\0'){
  61.         *dest++ = *src++;
  62.         if( ((--cc) == 0) && *src ) {
  63.             *dest++ = '.';
  64.             cc = 3;
  65.         }
  66.     }
  67.     xfree(core);
  68.     *dest = '\0';
  69. }
  70.  
  71. static int near
  72. fncmp(char *a,char *b)
  73. {
  74.     int i;
  75.  
  76.     for(;;){
  77.         if (*a == '.')
  78.             return -1;
  79.         if (*b == '.')
  80.             return 1;
  81.         if ((i = *a - *b++) != 0)
  82.             return i;
  83.         if (!*a++)
  84.             return -1;
  85.     }
  86. }
  87.  
  88. /* Provide additional information only on DIR */
  89. static void near
  90. print_free_space(file, n, d)
  91. FILE *file;
  92. int n, d;
  93. {
  94.     unsigned long free_bytes, total_bytes;
  95.     char s_free[15], s_total[15];
  96.     struct dfree dtable;
  97.     unsigned long bpcl;
  98.  
  99.     /* Find disk free space */
  100.     getdfree(d,&dtable);
  101.  
  102.     bpcl         = dtable.df_bsec  * dtable.df_sclus;
  103.     free_bytes  = dtable.df_avail * bpcl;
  104.     total_bytes = dtable.df_total * bpcl;
  105.  
  106.     sprintf(s_free,"%ld",free_bytes);
  107.     commas(s_free);
  108.     sprintf(s_total,"%ld",total_bytes);
  109.     commas(s_total);
  110.  
  111.     fprintf(file,"%s%d file(s). %s bytes free. Disk size %s bytes.\n",
  112.         (n & 1) ? "\n" : "",n,s_free,s_total);
  113. }
  114.  
  115. static void near
  116. format_fname_full(file, sbuf, full, n)
  117. FILE *file;
  118. struct ffblk *sbuf;
  119. int full, n;
  120. {
  121.     char line_buf[50];        /* for long dirlist */
  122.     char cbuf[20];            /* for making line_buf */
  123.  
  124.     strcpy(cbuf,sbuf->ff_name);
  125.     if (sbuf->ff_attrib & FA_DIREC) strcat(cbuf, "/");
  126.     if (full) {
  127.         /* Long form, give other info too */
  128.         sprintf(line_buf,"%-13s",cbuf);
  129.         if(sbuf->ff_attrib & FA_DIREC)
  130.             strcat(line_buf,"           ");/* 11 spaces */
  131.         else {
  132.             sprintf(cbuf,"%ld",sbuf->ff_fsize);
  133.             commas(cbuf);
  134.             sprintf(line_buf+strlen(line_buf),"%10s ",cbuf);
  135.         }
  136.         sprintf(line_buf+strlen(line_buf),"%2d:%02d %2d.%02d.%02d%s",
  137.           (sbuf->ff_ftime >> 11) & 0x1f,    /* hour */
  138.           (sbuf->ff_ftime >> 5) & 0x3f,        /* minute */
  139.           (sbuf->ff_fdate ) & 0x1f,            /* day */
  140.           (sbuf->ff_fdate >> 5) & 0xf,        /* month */
  141.           (sbuf->ff_fdate >> 9) + 80,        /* year */
  142.           (n & 1) ? "  " : "\n");
  143.         fputs(line_buf,file);
  144.     } else {
  145.         fprintf(file,"%s\n",cbuf);
  146.     }
  147. }
  148.  
  149. /* find the first or next file and lowercase it. */
  150. static int near
  151. nextname(command, name, sbuf)
  152. int command;
  153. char *name;
  154. struct ffblk *sbuf;
  155. {
  156.     int found = (command == 0) ? findfirst(name,sbuf,REGFILE) : findnext(sbuf);
  157.  
  158.     if((found = found == 0) != 0)
  159.         strlwr(sbuf->ff_name);
  160.  
  161.     return found;
  162. }
  163.  
  164. /* fix up the filename so that it contains the proper wildcard set */
  165. static char * near
  166. wildcardize(path)
  167. char *path;
  168. {
  169.     struct ffblk sbuf;
  170.     static char ourpath[64];
  171.     int i;
  172.  
  173.     /* Root directory is a special case */
  174.     if(path == NULLCHAR)
  175.         path = "/*.*";
  176.     else {
  177.         i = strlen(path);
  178.         i--;
  179.         if(path[i] == '\\' || path[i] == '/')
  180.             strcat(path,"*.*");
  181.         else if(path[i] == ':')
  182.             strcat(path,"/*.*");
  183.     }
  184.  
  185.     /* if they gave the name of a subdirectory, append \*.* to it */
  186.     if (nextname(0, path, &sbuf)
  187.       && (sbuf.ff_attrib & FA_DIREC)
  188.       && !nextname(1, path, &sbuf)) {
  189.         /* if there isn't enough room, give up -- it's invalid anyway */
  190.         if (strlen(path) + 4 > 63) return path;
  191.         strcpy(ourpath, path);
  192.         strcat(ourpath, "\\*.*");
  193.         return ourpath;
  194.     }
  195.  
  196.     return path;
  197. }
  198.  
  199. /* Create a directory listing in a temp file and return the resulting file
  200.  * descriptor. If full == 1, give a full listing; else return just a list
  201.  * of names.
  202.  */
  203. FILE *
  204. dir(path,full)
  205. char *path;
  206. int full;
  207. {
  208.     FILE *fp;
  209.  
  210.     if((fp = temp_file(0,1)) != NULLFILE){
  211.         getdir(path,full,fp);
  212.         rewind(fp);
  213.     }
  214.     return fp;
  215. }
  216.  
  217. /* wildcard filename lookup */
  218. int
  219. filedir(name,times,ret_str)
  220. char *name;
  221. int times;
  222. char *ret_str;
  223. {
  224.     static struct ffblk sbuf;
  225.     int rval = (times == 0) ? findfirst(name,&sbuf,REGFILE) : findnext(&sbuf);
  226.  
  227.     strcpy(ret_str,(rval == -1) ? "\0" : sbuf.ff_name);
  228.  
  229.     return rval;
  230. }
  231.  
  232. /* do a directory list to the stream full = 0 -> short form, 1 is long */
  233. int
  234. getdir(path,full,file)
  235. char *path;
  236. int full;
  237. FILE *file;
  238. {
  239.     struct ffblk sbuf;
  240.     int command = 0, n = 0, d = 0;
  241.     struct dirsort *head = NULLSORT, *here, *new, *next;
  242.  
  243.     path = wildcardize(path);
  244.  
  245.     for(;;){
  246.         if (!nextname(command, path, &sbuf))
  247.             break;
  248.         command = 1;    /* Got first one already... */
  249.         if (sbuf.ff_name[0] == '.')    /* drop "." and ".." */
  250.             continue;
  251.  
  252.         new = (struct dirsort *)mxallocw(sizeof(struct dirsort));
  253.         new->de = sbuf;    /* Copy contents of directory entry struct */
  254.  
  255.         /* insert it into the list */
  256.         if (!head || fncmp(new->de.ff_name, head->de.ff_name) < 0) {
  257.             insert_ptr(head, new);
  258.         } else {
  259.             struct dirsort *this;
  260.             for (this = head;
  261.                 this->next != NULLSORT;
  262.                 this = this->next)
  263.                 if (fncmp(new->de.ff_name, this->next->de.ff_name) < 0)
  264.                     break;
  265.             insert_ptr(this->next, new);
  266.         }
  267.     } /* infinite FOR loop */
  268.  
  269.     for (here = head; here; here = here->next)
  270.         format_fname_full(file,&here->de,full,++n);
  271.  
  272.     /* Give back all the memory we temporarily needed... */
  273.     while (head != NULLSORT) {
  274.         next = head->next;
  275.         xfree(head);
  276.         head = next;
  277.     }
  278.  
  279.     if(path[1] == ':')
  280.         d = (toupper(path[0])) - 64;
  281.     if(full)
  282.         print_free_space(file, n, d);
  283.  
  284.     return 0;
  285. }
  286.  
  287. /* Change working directory */
  288. int
  289. docd(argc,argv,p)
  290. int argc;
  291. char *argv[];
  292. void *p;
  293. {
  294.     char dirname[128], *s;
  295.  
  296.     if(argc < 2) {
  297.         if(getcwd(dirname,128) != NULLCHAR) {
  298.             while((s = strchr(dirname,'\\')) != NULLCHAR)
  299.                 *s = '/';
  300.             tprintf("%s\n",dirname);
  301.         }
  302.     } else if(chdir(argv[1]) == -1)
  303.         tprintf("Can't change to %s: %s\n",argv[1],sys_errlist[errno]);
  304.     return 0;
  305. }
  306.  
  307. /* List directory to console */
  308. int
  309. dodir(argc,argv,p)
  310. int argc;
  311. char *argv[];
  312. void *p;
  313. {
  314.     char tmpname[L_tmpnam+1];
  315.     FILE *fp;
  316.  
  317.     char *path = (argc < 2) ? "*.*" : argv[1];
  318.     char **margv = (char **)cxallocw(2,sizeof(char *));
  319.  
  320.     tmpnam(tmpname);
  321.     if((fp = open_file(tmpname,WRITE_TEXT,0,1)) == NULLFILE)
  322.         return -1;
  323.     getdir(path,1,fp);
  324.     fclose(fp);
  325.     margv[1] = strxdup(tmpname);
  326.     domore(2,margv,p);
  327.     xfree(margv[1]);
  328.     xfree(margv);
  329.     unlink(tmpname);
  330.     return 0;
  331. }
  332.  
  333. /* Delete file/s */
  334. int
  335. dodelete(argc,argv,p)
  336. int argc;
  337. char *argv[];
  338. void *p;
  339. {
  340.     int i;
  341.  
  342.     for(i = 1; i < argc; i++)
  343.         if(unlink(argv[i]) == -1)
  344.             tprintf("Can't delete %s: %s\n",argv[i],sys_errlist[errno]);
  345.     return 0;
  346. }
  347.  
  348. /* Rename file */
  349. int
  350. dorename(argc,argv,p)
  351. int argc;
  352. char *argv[];
  353. void *p;
  354. {
  355.     if(rename(argv[1],argv[2]) == -1)
  356.         tprintf("Can't rename %s to %s: %s\n",argv[1],argv[2],sys_errlist[errno]);
  357.     return 0;
  358. }
  359.  
  360. /* Create directory */
  361. int
  362. domkd(argc,argv,p)
  363. int argc;
  364. char *argv[];
  365. void *p;
  366. {
  367.     int i;
  368.  
  369.     for(i = 1; i < argc; i++)
  370.         if(mkdir(argv[i]) == -1)
  371.             tprintf("Can't make %s: %s\n",argv[i],sys_errlist[errno]);
  372.     return 0;
  373. }
  374.  
  375. /* Remove directory */
  376. int
  377. dormd(argc,argv,p)
  378. int argc;
  379. char *argv[];
  380. void *p;
  381. {
  382.     int i;
  383.  
  384.     for(i = 1; i < argc; i++)
  385.         if(rmdir(argv[i]) == -1)
  386.             tprintf("Can't delete %s: %s\n",argv[i],sys_errlist[errno]);
  387.     return 0;
  388. }
  389.  
  390. #ifdef    XXX
  391. static int
  392. getdir_nosort(path,full,file)
  393. char *path;
  394. int full;
  395. FILE *file;
  396. {
  397.     struct ffblk sbuf;
  398.     int command = 0, n = 0;        /* Number of directory entries */
  399.  
  400.     path = wildcardize(path);
  401.  
  402.     while(nextname(command, path, &sbuf)){
  403.         command = 1;    /* Got first one already... */
  404.         if (sbuf.ff_name[0] == '.')    /* drop "." and ".." */
  405.             continue;
  406.         format_fname_full(file, &sbuf, full, ++n);
  407.     }
  408.     if(full)
  409.         print_free_space(file, n, 0);
  410.     return 0;
  411. }
  412. #endif
  413.  
  414.